/** * Copyright (C) 2014 Premium Minds. * * This file is part of pm-persistence-utils. * * pm-persistence-utils is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * pm-persistence-utils is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with pm-persistence-utils. If not, see <http://www.gnu.org/licenses/>. */ package com.premiumminds.persistence; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Provider; import com.google.inject.persist.UnitOfWork; import com.premiumminds.persistence.PersistenceTransactionSynchronization.Status; public class JpaGuicePersistenceTransaction implements PersistenceTransaction { private static final Logger log = LoggerFactory.getLogger(JpaGuicePersistenceTransaction.class); private UnitOfWork unitOfWork; private Provider<EntityManager> emp; private ThreadLocal<List<PersistenceTransactionSynchronization>> sync = new ThreadLocal<List<PersistenceTransactionSynchronization>>(); private ThreadLocal<Boolean> started = new ThreadLocal<Boolean>(){ protected Boolean initialValue() { return false; }; }; @Inject public JpaGuicePersistenceTransaction(UnitOfWork unitOfWork, Provider<EntityManager> emp) { this.unitOfWork = unitOfWork; this.emp = emp; } public void start() { if(started.get()) throw new RuntimeException("transaction already started"); started.set(true); unitOfWork.begin(); emp.get().getTransaction().begin(); log.trace("Jpa transaction started"); } public void end() { if(!started.get()) throw new RuntimeException("transaction not started"); try { EntityTransaction transaction = emp.get().getTransaction(); PersistenceTransactionSynchronization.Status status; if(transaction.getRollbackOnly()){ transaction.rollback(); log.trace("Jpa transaction rolledback"); status = Status.ROLLEDBACK; } else { transaction.commit(); log.trace("Jpa transaction committed"); status = Status.COMMITTED; } if(sync.get()!=null){ for(PersistenceTransactionSynchronization s : sync.get()){ s.afterTransaction(status); } } } finally { sync.remove(); try { unitOfWork.end(); } finally { started.remove(); } } } public void setRollbackOnly() { if(!started.get()) throw new RuntimeException("transaction not started"); emp.get().getTransaction().setRollbackOnly(); } public boolean isRollbackOnly() { if(!started.get()) throw new RuntimeException("transaction not started"); return emp.get().getTransaction().getRollbackOnly(); } public void registerSynchronization( PersistenceTransactionSynchronization synchronization) { if(sync.get()==null) sync.set(new ArrayList<PersistenceTransactionSynchronization>()); sync.get().add(synchronization); } }